package com.share.shareplatform.sharegoods.config;


import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.share.shareplatform.pojo.exception.LogicException;
import com.share.shareplatform.util.Result;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@RestControllerAdvice
public class ExceptionConfig {

    public static List<Class<? extends Throwable>> ALL_HANDLER_EXCEPTION=new ArrayList<>();

    /*获取所有处理的异常*/
    @PostConstruct
    public void init(){
        Method[] methods = ExceptionConfig.class.getDeclaredMethods();
        for(Method method:methods){
            ExceptionHandler annotation = method.getAnnotation(ExceptionHandler.class);
            if(annotation==null){
                continue;
            }
            Class<? extends Throwable>[] value = annotation.value();

            List<Class<? extends Throwable>> list=new ArrayList<>(value.length);
            for (Class c:value){
                if(c.isAssignableFrom(Exception.class)){
                    continue;
                }
                list.add(c);
            }
            ALL_HANDLER_EXCEPTION.addAll(list);
        }
    }

    //参数不匹配
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result exceptionResult(MethodArgumentNotValidException e){
        BindingResult bindingResult = e.getBindingResult();

        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        String message = fieldErrors.get(0).getDefaultMessage();

        return Result.getInstance(200,message);
    }

    @ExceptionHandler({LogicException.class})
    public Result logicExceptionHandle(LogicException e){
        return Result.getInstance(505,e.getMessage());
    }


    @ExceptionHandler({Exception.class})
    public Result exceptionLogic(Exception e) throws Exception {
        //限流熔断异常特殊处理
        if(e.getCause()!=null &&e.getCause() instanceof BlockException){
            return Result.getInstance(505,"flow    limit");
        }

        return Result.getInstance(505,e.getMessage());
    }
/*

    @ExceptionHandler({BlockException.class})
    public Result blockExceptionHandler(BlockException e){
        System.out.println(e.getMessage());

        return Result.getInstance(505,"blockE");
    }

*/

    @ExceptionHandler({ConstraintViolationException.class})
    public Result methodParameterException(ConstraintViolationException e){
        String realError = e.getMessage().substring(e.getMessage().lastIndexOf(" ")+1, e.getMessage().length());
        return Result.getInstance(505,realError);
    }

    @ExceptionHandler({AccessDeniedException.class})
    public Result accessDeniedExceptionHandle(AccessDeniedException e){
        return Result.getInstance(505,"权限不足");
    }
}
